<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>iterator模式 &mdash; programming v0.1 documentation</title>
    <link rel="stylesheet" href="../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '0.1',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/translations.js"></script>
    <link rel="author" title="关于这些文档" href="../about.html" />
    <link rel="top" title="programming v0.1 documentation" href="../index.html" />
    <link rel="up" title="设计模式学习笔记" href="index.html" />
    <link rel="next" title="composite模式" href="composite.html" />
    <link rel="prev" title="template模式" href="template.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="composite.html" title="composite模式"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="template.html" title="template模式"
             accesskey="P">上一页</a> |</li>
        <li><a href="../index.html">programming v0.1 documentation</a> &raquo;</li>
          <li><a href="index.html" accesskey="U">设计模式学习笔记</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="iterator">
<h1>iterator模式<a class="headerlink" href="#iterator" title="永久链接至标题">¶</a></h1>
<div class="section" id="id1">
<span id="index-7"></span><span id="id2"></span><h2>iterator模式定义<a class="headerlink" href="#id1" title="永久链接至标题">¶</a></h2>
<p><strong>The Iterator Pattern</strong> provides a way to access the elements of an aggregate object sequentially
without exposing its underlying representation.</p>
<p><strong>迭代器模式</strong> 提供了一种对一种聚合体无需暴露其内部表示而又能顺序存取其元素的方法.</p>
</div>
<div class="section" id="id3">
<h2>问题描述<a class="headerlink" href="#id3" title="永久链接至标题">¶</a></h2>
<p>有两种不同的菜单,菜单的条目是相同的类型,但是每个菜单的条目所用的表示方式不同,一个为数组,一个为vector,
这时为了更好地提供统一的接口,我们可以使用 <strong>Iterator模式</strong> 来完成.</p>
<p>类图如下:</p>
<img alt="../_images/iterator_exp.png" src="../_images/iterator_exp.png" />
<p><strong>迭代器模式</strong> 类图如下:</p>
<img alt="../_images/iterator_class.JPG" src="../_images/iterator_class.JPG" />
</div>
<div class="section" id="id4">
<h2>具体代码<a class="headerlink" href="#id4" title="永久链接至标题">¶</a></h2>
<p>下载请点击 <a href="../_downloads/iterator.cpp"><strong class="xref">这里</strong></a></p>
<div class="highlight-c++"><table class="highlighttable"><tr><td class="linenos"><pre>  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168</pre></td><td class="code"><div class="highlight"><pre><span class="cp">#include&lt;iostream&gt;</span>
<span class="cp">#include&lt;vector&gt;</span>
<span class="cp">#include&lt;string&gt;</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Iterator</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">DinnaMenuIterator</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">PancakeMenuIterator</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">MenuItem</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">string</span> <span class="n">name</span><span class="p">;</span>
        <span class="kt">double</span> <span class="n">price</span><span class="p">;</span>

        <span class="n">MenuItem</span><span class="p">(</span><span class="n">string</span> <span class="n">name</span><span class="p">,</span> <span class="kt">double</span> <span class="n">price</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span><span class="p">;</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">price</span> <span class="o">=</span> <span class="n">price</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="n">string</span> <span class="n">getName</span><span class="p">(){</span><span class="k">return</span> <span class="n">name</span><span class="p">;}</span>
        <span class="kt">double</span> <span class="n">getPrice</span><span class="p">(){</span><span class="k">return</span> <span class="n">price</span><span class="p">;}</span>
<span class="p">};</span>

<span class="c">// PancakeMenu and DinnerMenu use the different internal representation of collection</span>
<span class="c">// so we can implement a unify Iterator class to offer the same interfaces</span>

<span class="k">class</span> <span class="nc">PancakeMenu</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">vector</span><span class="o">&lt;</span><span class="n">MenuItem</span><span class="o">*&gt;</span> <span class="n">items</span><span class="p">;</span>
        <span class="n">PancakeMenu</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">items</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="k">new</span> <span class="n">MenuItem</span><span class="p">(</span><span class="s">&quot;Potato&quot;</span><span class="p">,</span> <span class="mf">13.5</span><span class="p">));</span>
            <span class="n">items</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="k">new</span> <span class="n">MenuItem</span><span class="p">(</span><span class="s">&quot;tomato&quot;</span><span class="p">,</span> <span class="mf">33.5</span><span class="p">));</span>
            <span class="n">items</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="k">new</span> <span class="n">MenuItem</span><span class="p">(</span><span class="s">&quot;pancake&quot;</span><span class="p">,</span> <span class="mf">3.5</span><span class="p">));</span>
        <span class="p">}</span>

<span class="p">};</span>

<span class="k">class</span> <span class="nc">DinnerMenu</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">MenuItem</span><span class="o">*</span> <span class="n">menuitem</span><span class="p">[</span><span class="mi">6</span><span class="p">];</span>
        <span class="n">DinnerMenu</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">6</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
                <span class="n">menuitem</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
            <span class="n">menuitem</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="n">MenuItem</span><span class="p">(</span><span class="s">&quot;Noodle&quot;</span><span class="p">,</span> <span class="mf">45.5</span><span class="p">);</span>
            <span class="n">menuitem</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="n">MenuItem</span><span class="p">(</span><span class="s">&quot;Rice&quot;</span><span class="p">,</span> <span class="mf">32.4</span><span class="p">);</span>
        <span class="p">}</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">Iterator</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="kt">int</span> <span class="n">position</span><span class="p">;</span>
        <span class="n">Iterator</span><span class="p">()</span><span class="o">:</span><span class="n">position</span><span class="p">(</span><span class="mi">0</span><span class="p">){}</span>
        <span class="k">virtual</span> <span class="kt">bool</span> <span class="n">hasNext</span><span class="p">(){}</span>
        <span class="k">virtual</span> <span class="n">MenuItem</span><span class="o">*</span> <span class="n">next</span><span class="p">(){}</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">PancakeMenuIterator</span><span class="o">:</span><span class="k">public</span> <span class="n">Iterator</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">PancakeMenu</span> <span class="o">*</span><span class="n">pm</span><span class="p">;</span>
        <span class="n">PancakeMenuIterator</span><span class="p">(</span><span class="n">PancakeMenu</span> <span class="o">*</span><span class="n">pm</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">position</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">pm</span> <span class="o">=</span> <span class="n">pm</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">bool</span> <span class="n">hasNext</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">position</span><span class="o">&lt;</span><span class="n">pm</span><span class="o">-&gt;</span><span class="n">items</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">position</span><span class="o">&gt;=</span><span class="mi">0</span><span class="p">)</span>
                <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
            <span class="k">else</span>
                <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="n">MenuItem</span><span class="o">*</span> <span class="n">next</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="k">return</span> <span class="n">pm</span><span class="o">-&gt;</span><span class="n">items</span><span class="p">[</span><span class="n">position</span><span class="o">++</span><span class="p">];</span>
        <span class="p">}</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">DinnaMenuIterator</span><span class="o">:</span><span class="k">public</span> <span class="n">Iterator</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">DinnerMenu</span> <span class="o">*</span><span class="n">dm</span><span class="p">;</span>
        <span class="n">DinnaMenuIterator</span><span class="p">(</span><span class="n">DinnerMenu</span> <span class="o">*</span><span class="n">dm</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">position</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">dm</span> <span class="o">=</span> <span class="n">dm</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">bool</span> <span class="n">hasNext</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">position</span><span class="o">&lt;</span><span class="mi">6</span> <span class="o">&amp;&amp;</span> <span class="n">dm</span><span class="o">-&gt;</span><span class="n">menuitem</span><span class="p">[</span><span class="n">position</span><span class="p">]</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span>
                <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
            <span class="k">else</span>
                <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="n">MenuItem</span><span class="o">*</span> <span class="n">next</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="k">return</span> <span class="n">dm</span><span class="o">-&gt;</span><span class="n">menuitem</span><span class="p">[</span><span class="n">position</span><span class="o">++</span><span class="p">];</span>
        <span class="p">}</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">Waitress</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">PancakeMenuIterator</span> <span class="o">*</span><span class="n">pmi</span><span class="p">;</span>
        <span class="n">DinnaMenuIterator</span> <span class="o">*</span><span class="n">dmi</span><span class="p">;</span>

        <span class="n">Waitress</span><span class="p">(</span><span class="n">PancakeMenuIterator</span> <span class="o">*</span><span class="n">pmi</span><span class="p">,</span> <span class="n">DinnaMenuIterator</span> <span class="o">*</span><span class="n">dmi</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">pmi</span> <span class="o">=</span> <span class="n">pmi</span><span class="p">;</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">dmi</span> <span class="o">=</span> <span class="n">dmi</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">printAllMenu</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">printMenu</span><span class="p">(</span><span class="n">pmi</span><span class="p">);</span>
            <span class="n">printMenu</span><span class="p">(</span><span class="n">dmi</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="k">private</span><span class="o">:</span>
        <span class="kt">void</span> <span class="n">printMenu</span><span class="p">(</span><span class="n">Iterator</span> <span class="o">*</span><span class="n">iter</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">while</span><span class="p">(</span><span class="n">iter</span><span class="o">-&gt;</span><span class="n">hasNext</span><span class="p">())</span>
            <span class="p">{</span>
                <span class="n">MenuItem</span> <span class="o">*</span><span class="n">mi</span> <span class="o">=</span> <span class="n">iter</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">();</span>
                <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;Name: &quot;</span><span class="o">&lt;&lt;</span><span class="n">mi</span><span class="o">-&gt;</span><span class="n">getName</span><span class="p">()</span><span class="o">&lt;&lt;</span><span class="s">&quot;   Price:&quot;</span><span class="o">&lt;&lt;</span><span class="n">mi</span><span class="o">-&gt;</span><span class="n">getPrice</span><span class="p">()</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>
<span class="p">};</span>




<span class="kt">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">PancakeMenu</span> <span class="n">pm</span><span class="p">;</span>
    <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">pm</span><span class="p">.</span><span class="n">items</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">getName</span><span class="p">()</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>

    <span class="n">DinnerMenu</span> <span class="n">dm</span><span class="p">;</span>
    <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">dm</span><span class="p">.</span><span class="n">menuitem</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">getName</span><span class="p">()</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>

    <span class="n">PancakeMenuIterator</span> <span class="n">pmi</span><span class="p">(</span><span class="o">&amp;</span><span class="n">pm</span><span class="p">);</span>
    <span class="n">DinnaMenuIterator</span> <span class="n">dmi</span><span class="p">(</span><span class="o">&amp;</span><span class="n">dm</span><span class="p">);</span>

    <span class="c">// the following comments show the same interfaces of different Iterator</span>
    <span class="c">/*</span>
<span class="c">    cout&lt;&lt;&quot;###### Pancake using Iterator pattern #########&quot;&lt;&lt;endl;</span>
<span class="c">    while(pmi.hasNext())</span>
<span class="c">    {</span>
<span class="c">        MenuItem *mi = pmi.next();</span>
<span class="c">        cout&lt;&lt;&quot;Name:&quot;&lt;&lt;mi-&gt;getName()&lt;&lt;&quot;   Price:&quot;&lt;&lt;mi-&gt;getPrice()&lt;&lt;endl;</span>
<span class="c">    }</span>
<span class="c">    cout&lt;&lt;&quot;###### Dinner using Iterator pattern #########&quot;&lt;&lt;endl;</span>
<span class="c">    while(dmi.hasNext())</span>
<span class="c">    {</span>
<span class="c">        MenuItem *mi = dmi.next();</span>
<span class="c">        cout&lt;&lt;&quot;Name:&quot;&lt;&lt;mi-&gt;getName()&lt;&lt;&quot;   Price:&quot;&lt;&lt;mi-&gt;getPrice()&lt;&lt;endl;</span>
<span class="c">    }</span>
<span class="c">    */</span>

    <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;####### Waitress start ###############&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
    <span class="n">Waitress</span> <span class="n">waitress</span><span class="p">(</span><span class="o">&amp;</span><span class="n">pmi</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">dmi</span><span class="p">);</span>
    <span class="n">waitress</span><span class="p">.</span><span class="n">printAllMenu</span><span class="p">();</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>输出结果为:</p>
<div class="highlight-python"><pre>Potato
Noodle
####### Waitress start ###############
Name: Potato   Price:13.5
Name: tomato   Price:33.5
Name: pancake   Price:3.5
Name: Noodle   Price:45.5
Name: Rice   Price:32.4</pre>
</div>
</div>
<div class="section" id="id5">
<h2>面对新的需要<a class="headerlink" href="#id5" title="永久链接至标题">¶</a></h2>
<p>如果有新内部实现不同的集合,则只需:</p>
<ul class="simple">
<li>继承 <strong>Iterator</strong> 类</li>
<li>实现相应的接口即可</li>
</ul>
</div>
<div class="section" id="id6">
<h2>更多注意<a class="headerlink" href="#id6" title="永久链接至标题">¶</a></h2>
<p>设计准则:</p>
<p><strong>A class should have only one reason to change.</strong></p>
<p>也就是说一个类只能有一个 <strong>责任</strong>.这也是提高 <strong>内聚</strong> 的一种方法.</p>
</div>
<div class="section" id="id7">
<h2>参考更多<a class="headerlink" href="#id7" title="永久链接至标题">¶</a></h2>
<ol class="arabic simple">
<li><a class="reference external" href="http://en.wikipedia.org/wiki/Iterator_pattern">Iterator_Pattern</a></li>
</ol>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="../index.html">內容目录</a></h3>
            <ul>
<li><a class="reference external" href="">iterator模式</a><ul>
<li><a class="reference external" href="#id1">iterator模式定义</a></li>
<li><a class="reference external" href="#id3">问题描述</a></li>
<li><a class="reference external" href="#id4">具体代码</a></li>
<li><a class="reference external" href="#id5">面对新的需要</a></li>
<li><a class="reference external" href="#id6">更多注意</a></li>
<li><a class="reference external" href="#id7">参考更多</a></li>
</ul>
</li>
</ul>

            <h4>上一个主题</h4>
            <p class="topless"><a href="template.html"
                                  title="上一章">template模式</a></p>
            <h4>下一个主题</h4>
            <p class="topless"><a href="composite.html"
                                  title="下一章">composite模式</a></p>
            <h3>本页</h3>
            <ul class="this-page-menu">
              <li><a href="../_sources/designpattern/iterator.txt"
                     rel="nofollow">显示源代码</a></li>
            </ul>
          <div id="searchbox" style="display: none">
            <h3>快速搜索</h3>
              <form class="search" action="../search.html" method="get">
                <input type="text" name="q" size="18" />
                <input type="submit" value="搜索" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
              </form>
              <p class="searchtip" style="font-size: 90%">
              输入相关的模块，术语，类或者函数名称进行搜索
              </p>
          </div>
          <script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="composite.html" title="composite模式"
             >下一页</a> |</li>
        <li class="right" >
          <a href="template.html" title="template模式"
             >上一页</a> |</li>
        <li><a href="../index.html">programming v0.1 documentation</a> &raquo;</li>
          <li><a href="index.html" >设计模式学习笔记</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; 版权所有 2009, zhutao.iscas@gmail.com.
      使用 <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.1.
    </div>
  </body>
</html>